import re
from collections import OrderedDict
from django.conf import settings
from django.utils.module_loading import import_string
from django.urls import URLResolver, URLPattern


def check_url_exclude(url):
    """
    排除一些特定的URL
    :param url:
    :return:
    """
    for regex in settings.ALL_URL_EXCLUDE:
        if re.match(regex, url):
            return True


def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
    """
    递归获取URL
    :param pre_namespace: 当前的 urlpatterns所属的 namespace
    :param pre_url: pre_namespace对应的 url
    :param urlpatterns: 当前文件下的 urlpatterns列表
    :param url_ordered_dict: 保存获取到的所有 url
    :return:
    """
    for item_url in urlpatterns:
        if isinstance(item_url, URLPattern):  # 非路由分发
            if not item_url.name:
                continue

            if pre_namespace:
                current_url_name = "%s:%s" % (pre_namespace, item_url.name)
            else:
                current_url_name = item_url.name

            # item_url.pattern: 获取当前 path对象对应的 url(非完整 url)
            current_url = pre_url + str(item_url.pattern)
            # current_url = current_url.replace('^', '').replace('$', '')

            if check_url_exclude(current_url):
                continue

            url_ordered_dict[current_url_name] = {'name': current_url_name, 'url': current_url}

        elif isinstance(item_url, URLResolver):  # 路由分发
            if pre_namespace:
                if item_url.namespace:
                    re_namespace = "%s:%s" % (pre_namespace, item_url.namespace)
                else:
                    re_namespace = pre_namespace
            else:
                if item_url.namespace:
                    re_namespace = item_url.namespace
                else:
                    re_namespace = None

            # item_url.url_patterns: 返回当前 URLResolver对象对应的文件中的 urlpatterns列表
            recursion_urls(re_namespace, pre_url + str(item_url.pattern), item_url.url_patterns, url_ordered_dict)


def get_all_url_dict():  # 获取所有有name的url
    url_ordered_dict = OrderedDict()

    init_url = import_string(settings.ROOT_URLCONF)
    recursion_urls(None, '/', init_url.urlpatterns, url_ordered_dict)  # 递归去获取所有的路由

    return url_ordered_dict
